#ifndef __M_CONNECTION_H__
#define __M_CONNECTION_H__
#include "mq_channal.hpp"

namespace yqx{
    class Connection{
        public:
            using ptr = std::shared_ptr<Connection>;
            Connection(const muduo::net::TcpConnectionPtr& conn, const ProtobufCodecPtr& codec, const ConsumerManager::ptr& cmp, const VirtualHost::ptr& vhp, const ThreadPool::ptr pool):
            _conn(conn), _codec(codec), _cmp(cmp), _vhp(vhp), _thread_pool(pool), _pchannals(std::make_shared<ChannalManager>())
            {}
            //打开一个信道
            void openChannal(const openChannelRequestPtr& req){
                bool ret = _pchannals->openChannal(req->cid(), _conn, _codec, _cmp, _vhp, _thread_pool);
                if(ret == false){
                    return basicResponse(false, req->rid(), req->cid());
                }
                basicResponse(true, req->rid(), req->cid());
            }
            //关闭信道
            void closeChannal(const closeChannelRequestPtr& req){
                _pchannals->closeChannal(req->cid());
                basicResponse(true, req->rid(), req->cid());
            }
            //获取一个信道
            Channal::ptr getChannal(const std::string cname){
                return _pchannals->getChannal(cname);
            }
        private:
            void basicResponse(bool ok, const std::string& rid, const std::string& cid){
                basicCommonResponse resp;
                resp.set_ok(ok);
                resp.set_rid(rid);
                resp.set_cid(cid);
                _codec->send(_conn, resp);
            }
        private:
            muduo::net::TcpConnectionPtr _conn;
            ProtobufCodecPtr _codec;
            ConsumerManager::ptr _cmp;
            VirtualHost::ptr _vhp;
            ThreadPool::ptr _thread_pool;
            ChannalManager::ptr _pchannals;
    };
    class ConnectionManager{
        public:
            using ptr = std::shared_ptr<ConnectionManager>;
            ConnectionManager(){}
            //创建连接
            void createConnection(const muduo::net::TcpConnectionPtr& conn, const ProtobufCodecPtr& codec, const ConsumerManager::ptr& cmp, const VirtualHost::ptr& vhp, const ThreadPool::ptr pool){
                std::unique_lock<std::mutex> lock(_mtx);
                auto it = _conns.find(conn);
                if(it != _conns.end())
                    return;
                auto new_conn = std::make_shared<Connection>(conn, codec, cmp, vhp, pool);
                _conns.insert(std::make_pair(conn, new_conn));
            }
            //删除连接
            void deleteConnection(const muduo::net::TcpConnectionPtr& conn){
                std::unique_lock<std::mutex> lock(_mtx);
                _conns.erase(conn);
            }
            //获取一个连接
            Connection::ptr getConnection(const muduo::net::TcpConnectionPtr& conn){
                std::unique_lock<std::mutex> lock(_mtx);
                auto it = _conns.find(conn);
                if(it == _conns.end())
                    return nullptr;
                return it->second;
            }
        private:
            std::mutex _mtx;
            std::unordered_map<muduo::net::TcpConnectionPtr, Connection::ptr> _conns;
    };
}
#endif